package perfumecabinet

import (
	"context"
	"fmt"
	"strings"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/forum/model"
	"mall/service/forum/rpc/internal/svc"
	"mall/service/forum/rpc/types/forum"

	"github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetPerfumeCabinetListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetPerfumeCabinetListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPerfumeCabinetListLogic {
	return &GetPerfumeCabinetListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// 香水柜列表
func (l *GetPerfumeCabinetListLogic) GetPerfumeCabinetList(in *forum.BaseListReq) (*forum.PerfumeCabinetListResp, error) {
	if in.Filter == nil || len(*in.Filter) == 0 {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	preloadMap, eagerLoadMap := modelx.ParsePreloadAndEagerLoad(in.Preload, in.EagerLoad)
	logrus.Info(fmt.Sprintf("GetPerfumeCabinetList preloadMap: %+v", preloadMap))
	// map[perfumeCabinet:[Id UserId ObjectId ObjectType Status UpdatedAt] total:[]]
	// logrus.Info(fmt.Sprintf("GetPerfumeCabinetList eagerLoadMap: %+v", eagerLoadMap))
	// map[object_type:map[equalTo:[1]] status:map[equalTo:[1]] user_id:map[equalTo:[10021]]]

	forumPerfumeCabinetEntityName := model.RpcEntityNames.ForumPerfumeCabinet
	if _, ok := model.RpcEntityPreloadMap[forumPerfumeCabinetEntityName]; !ok {
		return &forum.PerfumeCabinetListResp{}, nil
	}

	forumPerfumeCabinetRepositoryName := model.RepositoryNames.ForumPerfumeCabinet
	columnMap, ok := model.RepositoryPreloadMap[forumPerfumeCabinetRepositoryName]
	if !ok {
		return &forum.PerfumeCabinetListResp{}, nil
	}

	var selectCols []string
	if preloadFields, ok := preloadMap[forumPerfumeCabinetEntityName]; ok {
		selectCols = modelx.ParseSelectColumns(preloadFields, columnMap)
	}

	filterMap := modelx.ParseFilter(in.Filter, columnMap)
	logrus.Info(fmt.Sprintf("GetPerfumeCabinetList filterMap: %+v", filterMap))
	if filterMap == nil {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	filterMap[model.ForumUserPerfumeCabinetColumns.Status] = map[string][]any{
		"equalTo": {globalkey.StatusEnabled},
	}

	orderBy := modelx.ParseSorter(in.Sorter, columnMap)
	logrus.Info(fmt.Sprintf("GetPerfumeCabinetList orderBy: %s", orderBy))
	if len(orderBy) == 0 {
		orderBy = model.ForumUserPerfumeCabinetColumns.ID + " DESC"
	}

	res, count, err := l.svcCtx.ForumPerfumeCabinet.GetList(l.ctx, model.M{
		"offset":  in.Offset,
		"limit":   in.Limit,
		"orderBy": orderBy,
		"select":  strings.Join(selectCols, ","),
	}, 2, filterMap)
	if err != nil {
		return nil, err
	}

	hasNextPage, hasPreviousPage := modelx.ParseCount(count)
	resp := &forum.PerfumeCabinetListResp{
		HasNextPage:     &hasNextPage,
		HasPreviousPage: &hasPreviousPage,
	}

	var total int64
	if len(res) > 0 {
		if eagerLoadEntities, ok := eagerLoadMap[forumPerfumeCabinetEntityName]; ok {
			for _, entity := range eagerLoadEntities {
				if entity == "total" {
					_, total, err = l.svcCtx.ForumPerfumeCabinet.GetList(l.ctx, model.M{}, 0, filterMap)
					if err != nil {
						total = 0
					}
					continue
				}
			}
		}

		for _, v := range res {
			resp.List = append(resp.List, &forum.PerfumeCabinetInfo{
				Id:         &v.ID,
				UserId:     &v.UserID,
				PlatformId: pointy.GetPointer(uint64(v.PlatformID)),
				ObjectId:   &v.ObjectID,
				ObjectType: pointy.GetPointer(uint32(v.ObjectType)),
				Status:     pointy.GetPointer(uint32(v.Status)),
				CreatedAt:  pointy.GetPointer(modelx.FormatTime(v.CreatedAt, "")),
				UpdatedAt:  pointy.GetPointer(modelx.FormatTime(v.UpdatedAt, "")),
			})
		}
	}
	resp.Total = uint64(total)

	return resp, nil
}
